# -*- coding: UTF-8 -*-


import sys
from sqlalchemy import func
from sqlalchemy import and_, or_
from sqlalchemy import Boolean, Column, DateTime, Integer, String, Index, Table, ForeignKey, text, JSON, TEXT, distinct
from sqlalchemy.orm import Session, relationship
from common.database import Base
from common.database import SessionMixin
from common.utils import is_empty
from core.logger import logger

from app.monitor_metrics.models.prom_alarm_template import PromAlarmTemplate
from app.manage_notice.models.manage_notice_team import ManageNoticeTeam
from app.monitor_metrics.models.prom_department import PromDepartment



__all__ = ['PromHostGroup']

class PromHostGroup(Base, SessionMixin):
    '''
    主机组
    '''
    __tablename__ = "prom_host_group"
    name = Column(String(64), nullable=False, comment='组名')
    department_uuid = Column(Integer, nullable=False, comment='所属部门')
    notice_teams_uuid = Column(JSON, nullable=False, default=[], comment='通知小组')
    templates_uuid = Column(JSON, nullable=True, default=[], comment='主机组关联的告警模板')
    comment = Column(String(256), nullable=True, comment='主机组说明')

    hosts = relationship("PromHostInfo", backref="prom_host_group")


    __table_args__ = (
        Index('idx_prom_host_group_name', 'name', unique=True),
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic'
        }
    )

    def __repr__(self):
        return f"<prom_host_group='{self.name}'>"


    def object_to_dict(self, db: Session):
        result = {
            key: getattr(self, key)
            for key in self.__mapper__.c.keys()
        }
        result["hosts"] = [
            host.object_to_dict(db)
            for host in self.hosts
        ]
        result["department"] = PromDepartment.get_object_info_by_uuid(db, result["department_uuid"])["name"]


        # 方便前端直接展示名称
        result["notice_teams_name"] = []
        if result["notice_teams_uuid"]:
            for notice_team_uuid in result["notice_teams_uuid"]:
                notice_team_info = ManageNoticeTeam.get_object_info_by_uuid(db, notice_team_uuid)
                result["notice_teams_name"].append(notice_team_info["name"])

        # 方便前端直接展示名称
        result["templates_name"] = []
        if result["templates_uuid"]:
            for template_uuid in result["templates_uuid"]:
                template_info = PromAlarmTemplate.get_object_info_by_uuid(db, template_uuid)
                result["templates_name"].append(template_info["name"])

        return result



    @classmethod
    def get_object_info_by_template(cls, db: Session, template_uuid: str):
        host_groups_info = db.query(cls).filter(
            func.json_contains(cls.templates_uuid, str(template_uuid)) == 1
        ).all()

        # func.json_contains(Foo.bar, func.json_object("some_field", "some_value"))
        result = [
            cls.get_object_info_by_uuid(db, item.uuid)
            for item in host_groups_info
        ]

        return result


    @classmethod
    def add_template(cls, db: Session, host_group_uuid: int, template_uuid: int):
        host_group = cls.get_object_info_by_uuid(db, host_group_uuid)
        host_group.pop("hosts")
        host_group.pop("notice_teams_name")
        host_group.pop("templates_name")
        host_group.pop("department")
        if host_group["templates_uuid"]:
            host_group["templates_uuid"].append(template_uuid)
        else:
            host_group["templates_uuid"] = [template_uuid]
        result = cls.update(db, host_group)
        if not result:
            logger.error(f"update host group bind templates to database failed")
            return False

        return True


    @classmethod
    def delete_template(cls, db: Session, host_group_uuid: int, template_uuid: int):
        host_group = cls.get_object_info_by_uuid(db, host_group_uuid)
        host_group.pop("hosts")
        host_group.pop("notice_teams_name")
        host_group.pop("templates_name")
        host_group.pop("department")
        host_group["templates_uuid"].remove(template_uuid)
        result = cls.update(db, host_group)
        if not result:
            logger.error(f"update host group bind templates to database failed")
            return False
        return True


    @classmethod
    def get_object_info_by_notice_team(cls, db: Session, notice_team_uuid: str):
        object_info = db.query(cls).filter(
            func.json_contains(cls.notice_teams_uuid, str(notice_team_uuid)) == 1
        ).to_dict()

        return object_info


    @classmethod
    def get_object_info_by_department(cls, db: Session, department_uuid: int):
        object_info = db.query(cls).filter(
            cls.department_uuid == department_uuid
        ).to_dict()

        return object_info

    @classmethod
    def get_object_info_by_light(cls, db: Session, uuid: int):
        object_info = db.query(cls).filter(
            cls.uuid == uuid
        ).to_dict_first()

        object_info["department"] = PromDepartment.get_object_info_by_uuid(db, object_info["department_uuid"])["name"]

        return object_info









